# -*- coding: ascii -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
#
# tombogrep.py  - a grep-like search tool
# Copyright (C) 2007  Chris Clark
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""
Tombo Grep
Recursively Search Tombo plain text and encrypted notes.
Can either use --argument or grep like search and path terms without --search_term and --dir_name

Usage: %prog [options] args
    -s, --search_term=STRING: Term to search for, if omitted, args is used instead
    -r, --regex_search:            Treat search term as a regex (default is to treat as literal word/phrase)
    -i, --ignore_case:      Case insensitive search
    -d, --dir_name=PATH: PATH Name Directory of notes to search (or file name), if omitted, args is used instead
    -n, --line_numbers:     Print line number with output lines
    -e, --search_encrypted: Search encrypted files
    -p, --password=PASSWORD: Password to use for all encrypted notes (if omitted will be prompted for password, specifying password at command line can be a security risk as password _may_ be visible in process/task list and/or shell history)
    -t, --time: Print query search time
"""
## FIXME make MANDATORY an option
## FIXME make DIRNAME a "type"

import sys
import time

import optionparse
#import weboptionparse as optionparse

from pytombo.search import search_iter, SearchCancelled
from pytombo.tombonote import gen_caching_get_password, gen_static_password, remove_leading_path


def main(argv=None):
    if argv is None:
        argv = sys.argv

    opt, args = optionparse.parse(__doc__, argv[1:])
    def usage_error(msg=''):
        raise SystemExit(optionparse.optionstring.replace("%prog",sys.argv[0]) + '\n' + msg) ## fixme make this stuff cass based in module, optionstring global is not cool...
    
    if opt.search_term:
        search_term = opt.search_term
    else:
        try:
            search_term = args[0]
        except IndexError, info:
            ## missing search term
            #raise optionparse.Usage('missing search term')
            #optionparse.exit_exception() ##FIXME update exit_exception to append error text to end of usage instead-of "instead of" logic
            #optionparse.exit('missing search term') ##FIXME update exit_exception to append error text to end of usage instead-of "instead of" logic
            usage_error('ERROR: Missing search term')

    path_to_search = opt.dir_name
    if not path_to_search:
        try:
            path_to_search = args[1] ## FIXME TODO glob all args
        except IndexError, info:
            usage_error('ERROR: Missing search path/directory')
    
    line_numbers = opt.line_numbers == True
    
    search_is_regex = opt.regex_search == True
    
    ignore_case = opt.ignore_case
    
    search_encrypted = opt.search_encrypted
    
    if opt.password:
        password_func = gen_static_password(opt.password).gen_func()
    else:
        caching_console_password_prompt = gen_caching_get_password(dirname=path_to_search).gen_func()
        password_func = caching_console_password_prompt
    
    if opt.time:
        start_time = time.time()
    try:
        print (search_term, path_to_search, search_is_regex, ignore_case, search_encrypted, password_func)
        for hit in search_iter(search_term, path_to_search, search_term_is_a_regex=search_is_regex, ignore_case=ignore_case, search_encrypted=search_encrypted, get_password_callback=password_func):
            filename, hit_detail = hit
            filename = remove_leading_path(path_to_search, filename)
            if filename:
                filename = '%s:' % filename
            else:
                # Single file grep, rather than recursive search
                # do not want filename
                filename = ''
            for result_hit_line, result_hit_text in hit_detail:
                if line_numbers:
                    print '%s%d:%s' % (filename, result_hit_line, result_hit_text)
                else:
                    print '%s%s' % (filename, result_hit_text)
    except SearchCancelled, info:
        print 'search cancelled because of', info
    if opt.time:
        end_time = time.time()
        search_time = end_time - start_time
        print 'Query time: %.2f seconds' % search_time


    return 0


if __name__ == "__main__":
    sys.exit(main())
    '''
    import timeit

    def Timeit(func,number=10000,module="__main__"):
        """ A wrapper which can
        be used to time any function """

        name = func.__name__
        t = timeit.Timer("%s()"%name, "from %s import %s" % (module, name))
        result_time = t.timeit(number=number)/number
        return "%.2f usec/pass (%.2f sec/pass)" % (1000000*result_time, result_time)

    
    num_tests = 1
    num_tests = 5
    test_func=main
    time_took = Timeit(test_func, num_tests)
    print test_func.__name__, '(%d iterations)'%num_tests, time_took
    '''
